package finalgame.GUI;

import org.lwjgl.input.Keyboard;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.opengl.Texture;

import finalgame.Engine.EnumOptions;
import finalgame.Engine.trainer.Trainer;
import finalgame.GUI.stage.Element;
import finalgame.GUI.stage.Stage;
import finalgame.Graphics.Animation;
import finalgame.Graphics.GraphicsConstants;
import finalgame.Graphics.Location;
import finalgame.Graphics.Render2D;
import finalgame.Graphics.RenderEngine;
import finalgame.Graphics.RenderObj;

public class Character extends Element implements RenderObj {
	public enum Direction {
		UP(0, "up", 0, -1.5, -90),
		LEFT(1, "left", -2, 0, 180),
		RIGHT(2, "right", 2, 0, 0),
		DOWN(3, "down", 0, 1.5, 90);
		
		protected int dir;
		protected String name;
		protected Location delta;
		protected double angle;
		
		public int getDir() {
			return dir;
		}
		
		public String getName() {
			return name;
		}
		
		public Location getDelta() {
			return delta;
		}
		
		public double getAngle() {
			return angle;
		}
		
		/**
		 * Get the index-th option
		 * @param index
		 * @return
		 */
		public static Direction getDirection(int index) {
			Direction vals[] = values();
			int len = vals.length;

			for (int i = 0; i < len; i++) {
				Direction direction = vals[i];

				if (direction.returnOrdinal() == index) {
					return direction;
				}
			}

			return null;
		}

		public int returnOrdinal() {
			return ordinal();
		}
		
		public boolean facing(Direction other) {
			return (Math.abs(angle) + Math.abs(other.angle)) == 180 && this != other;
		}
		
		private Direction(int dir, String name, double dx, double dy, double angle) {
			this.dir = dir;
			this.name = name;
			this.delta = new Location(dx, dy);
			this.angle = angle;
		}
	}
	
	protected Direction direction;
	protected int walk_index;
	public Location vLoc;
	public boolean moved;
	
	protected String characterName;
	protected Trainer me;

	protected boolean isKeyDown;
	protected Stage stage;
	
	public Character(String name) {
		direction = Direction.DOWN;
		me = new Trainer();
		characterName = name;
		me.setName(name);
		vLoc = new Location(0, 0);
		me.setLoc(vLoc);
		solid = true;
		bounds = new Rectangle(0, 0, 20, 32);
	}
	
	public void setTrainer(Trainer t) {
		me = t;
	}
	
	public void setDirection(Direction direction) {
		this.direction = direction;
		RenderEngine.getAnimation(characterName + "." + direction.getName()).restart();
	}
	
	public Direction getDirection() {
		return direction;
	}
	
	public void setLocation(Location loc) {
		this.vLoc = stage.bound(loc);
		me.setLoc(vLoc);
		bounds.setX((float) loc.x() - bounds.getWidth() / (2 * (float) stage.getWScale()));
		bounds.setY((float) loc.y() - bounds.getHeight() / (2 * (float) stage.getHScale()));
	}
	
	public void translate(double dx, double dy) {
		if(stage == null) return;
		setLocation(new Location(vLoc.x() + dx, vLoc.y() + dy));
		moved = true;
	}
	
	public void translate(Location delta) {
		translate(delta.x(), delta.y());
	}
	
	public void updateBounds() {
		bounds.setWidth(20);
		bounds.setHeight(20);
		bounds.setX((float) vLoc.x() - bounds.getWidth() / 2);
		bounds.setY((float) vLoc.y() - bounds.getHeight() / 2);
	}
	
	public void render() {
		Location renderLoc = new Location(0, 0);
		if(stage != null) {
			renderLoc = stage.getPRenderLoc(vLoc);
			if(renderLoc == null) return;
		}
		String type = me.getClass().getSimpleName().substring("trainer".length()).toLowerCase();
		Texture myTex = RenderEngine.getSprite(type);
		Render2D.drawTex((int) renderLoc.x(),
				(int) renderLoc.y(), myTex);
	}
	
	public void update() {
	}
	
	public void setStage(Stage s) {
		stage = s;
		vLoc = s.bound(vLoc);
	}

	public Trainer getTrainer() {
		return me;
	}
}
